<?php 
/* $Id$ */
/**
 * @package SwfUploadComponent
 * @subpackage controllers.components
 */
class MultiFileUploadComponent extends Object {
    var $content_types = array(
        'jpeg'	=>	'image/jpeg',
    	'jpg'	=>	'image/jpeg',
    	'png'	=>	'image/png',
    	'gif'	=>	'image/gif',
    );
    /* component configuration */
    var $name = 'MultiFileUploadComponent';
    var $params = array();
    var $errorCode = null;
    var $errorMessage = null;
    
    // file and path configuration
    var $uploadpath;
    var $overwrite = false;
    var $encode_filename = true;
    var $filename;
    var $postName = 'Filedata';

    
    var $_properties = array(
		"AttachTypeAllowed"		=>	"jpg,jpeg,gif,png,swf,txt,zip,rar,doc,pdf,xls,docx, flv, mpeg, avi",
		"ImgTypes"			     =>	"jpg,jpeg,gif,png",		
		"MaxSize"				=>	1024000000, // 9MB
		"MaxWidth"				=>	3000,
		"MaxHeight"				=>	3000,
	);
	
    /**
     * Contructor function
     * @param Object &$controller pointer to calling controller
     */
    function startup(&$controller) {
        // initialize members
        $this->uploadpath = 'files' . DS . 'uploads' . DS;

        //keep tabs on mr. controller's params
        $this->params = $controller->params;

    }
    
    /**
     * Uploads a file to location
     * @return boolean true if upload was successful, false otherwise.
     */
    function upload() {
        $attachment = "";
		$attachment_name = "";
		$attachment_size = "";
		$extension = "";
		$check = true;
		
		$returnArr = array();
		if (is_array($_FILES)) {
			foreach ($_FILES['FileField']['name'] as $key => $value) {
				if ($_FILES['FileField']["size"][$key] > 0) {
					if ($this->check_validate($_FILES,$key)) {
						continue;
					} else {
						$check = false;
						//$this->setError(1000, 'File system save failed.');
						break;
					}
				}
			}
			
			if ($check) {
				$returnArr = array();
				foreach ($_FILES['FileField']['name'] as $key => $value) {
					if ($_FILES['FileField']['size'][$key] > 0)
						$returnArr[$key] = $this->write($_FILES,$key);
				}
			} else {
				throw new Exception($this->errorMessage);
				return false;
			}
		} else {
			$this->setError(1000, 'File system save failed.');
			return false;
		}
		return $returnArr;
    }

    /**
     * finds a unique name for the file for the current directory
     * @param array an array of filenames which exist in the desired upload directory
     * @return string a unique filename for the file
     */
    function findUniqueFilename($existing_files = null) {
        // append a digit to the end of the name
        $filenumber = 0;
        $filesuffix = '';
        $fileparts = explode('.', $this->filename);
        $fileext = '.' . array_pop($fileparts);
        $filebase = implode('.', $fileparts);

        if (is_array($existing_files)) {
            do {
                $newfile = $filebase . $filesuffix . $fileext;
                $filenumber++;
                $filesuffix = '(' . $filenumber . ')';
            } while (in_array($newfile, $existing_files));
        }
        
        return $newfile;
    }

    /**
     * moves the file to the desired location from the temp directory
     * @return boolean true if the file was successfully moved from the temporary directory to the desired destination on the filesystem
     */
    function write($postFile,$index=-1) {
        // Include libraries
        if (!class_exists('Folder')) {
            uses ('folder');
        }
        
        $moved = false;
        $folder = new Folder($this->uploadpath, true, 0755);
        //$folder = true;
        if (!$folder) {
            $this->setError(1500, 'File system save failed.', 'Could not create requested directory: ' . $this->uploadpath);
        } else {
        	$attachment = $postFile['FileField']["tmp_name"][$index];
			$attachment_name = strtolower($postFile['FileField']['name'][$index]);
	    	$attachment_size = $postFile['FileField']['size'][$index];
	    	$extension = substr(strrchr($attachment_name,"."),1);
	    	
        	if ($this->encode_filename) {
				$newpath = "";
				$unique = substr(md5(microtime()),0,32);
				$this->filename = $unique.".".$extension;
				
        	} else if (!$this->overwrite) {
                $contents = $folder->read();  //get directory contents
                $this->filename = $attachment_name;
                $this->filename = $this->findUniqueFilename($contents[1]);  //pass the file list as an array
            }
	        $newpath = $this->uploadpath.$this->filename;

	        if (is_uploaded_file($attachment)) {
	        	$moved = move_uploaded_file($attachment, $newpath);
				$filesize=filesize($newpath);
				if ($filesize!=$attachment_size || strstr($newpath,"..")!="") {
					@unlink($newpath);
					$this->setError(1000, 'File system save failed.');
				}
			}
        }
        if ($moved) {
        	if ($this->encode_filename) {
        		return array(
        			"index"			=>	$index,
        			"encrypt_name"	=>	$this->filename,
        			"original_name"	=>	$attachment_name,
        			"size"			=>	$attachment_size,
        			"extension"		=>	$extension
        		);
        	}
        	else
        		return array(
        			$index=>$this->filename,
        			"size"			=>	$attachment_size,
        			"extension"		=>	$extension
        		);
        }
        else
        	return false;
    }

    /**
     * parses file upload error code into human-readable phrase.
     * @param int $err PHP file upload error constant.
     * @return string human-readable phrase to explain issue.
     */
    function getUploadErrorMessage($err) {
        $msg = null;
        switch ($err) {
            case UPLOAD_ERR_OK:
                break;
            case UPLOAD_ERR_INI_SIZE:
                $msg = ('The uploaded file exceeds the upload_max_filesize directive ('.ini_get('upload_max_filesize').') in php.ini.');
                break;
            case UPLOAD_ERR_FORM_SIZE:
                $msg = ('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.');
                break;
            case UPLOAD_ERR_PARTIAL:
                $msg = ('The uploaded file was only partially uploaded.');
                break;
            case UPLOAD_ERR_NO_FILE:
                $msg = ('No file was uploaded.');
                break;
            case UPLOAD_ERR_NO_TMP_DIR:
                $msg = ('The remote server has no temporary folder for file uploads.');
                break;
            case UPLOAD_ERR_CANT_WRITE:
                $msg = ('Failed to write file to disk.');
                break;
            default:
                $msg = ('Unknown File Error. Check php.ini settings.');
        }
        
        return $msg;
    }

    /**
     * sets an error code which can be referenced if failure is detected by controller.
     * note: the amount of info stored in message depends on debug level.
     * @param int $code a unique error number for the message and debug info
     * @param string $message a simple message that you would show the user
     * @param string $debug any specific debug info to include when debug mode > 1
     * @return bool true unless an error occurs
     */

    function setError($code = 1, $message = 'An unknown error occured.', $debug = '') {
        $this->errorCode = $code;
        $this->errorMessage = $message;
//        if (DEBUG) {
//            //$this->errorMessage .= $debug;
//        }
        //echo $message;
        return true;
    }

    private function check_validate($postFile,$index=-1)
	{
		$attachment = $postFile['FileField']["tmp_name"][$index];
	   	$attachment_name = strtolower($postFile['FileField']["name"][$index]);
	   	$attachment_size = $postFile['FileField']["size"][$index];
	   	$extension = substr(strrchr($attachment_name,"."),1);
	   	//Debug(array($attachment,$attachment_name,$attachment_size,$extension));
	   	if ($attachment_size == 0)
	   	{
	   		$this->setError(2000, __("Không file nào được tải lên.",true), __("Không file nào được tải lên.",true));
	   		//$this->Session->set('No file was uploaded.');
	   		return false;
	   	}
		if (!eregi($extension,$this->_properties['AttachTypeAllowed']) && $this->_properties['AttachTypeAllowed'] != "*") {
			$this->setError(2000, __('Định dạng file này không cho phép.', true), __('Định dạng file này không cho phép.', true));
			//$this->Session->set('The type of uploaded file is invalid.');
	   		return false;
		}
		
		if ($attachment_size > $this->_properties['MaxSize']) {
			$this->setError(2000, __('File upload vượt quá dung lượng cho phép.', true), __('File upload vượt quá dung lượng cho phép', true));
	   		return false;
		}
		
		if (eregi($extension,$this->_properties['ImgTypes'])) {
			$sizeinfo = getimagesize($attachment);

			if ($sizeinfo[0] > $this->_properties['MaxWidth'] || $sizeinfo[1] > $this->_properties['MaxHeight']) {
				$this->setError(2000, __('File upload vượt quá kích thước cho phép.', true), __('File upload vượt quá kích thước cho phép', true));
	   			return false;
			}
		}
        if (!eregi($extension,$this->_properties['ImgTypes']) && $this->_properties['ImgTypes'] != "*") {
			$this->setError(2000, __('Định dạng file này không cho phép.', true), __('Định dạng file này không cho phép.', true));
			//$this->Session->set('The type of uploaded file is invalid.');
	   		return false;
		}
        
		return true;
	}
	
	function getContentType($extension) {
		return $this->content_types[$extension];
	}
}
?>